{
 "cells": [
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T13:50:12.192890Z",
     "start_time": "2025-01-16T13:50:12.187380Z"
    }
   },
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "    \n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=12, micro=3, releaselevel='final', serial=0)\n",
      "matplotlib 3.10.0\n",
      "numpy 1.26.4\n",
      "pandas 2.2.3\n",
      "sklearn 1.6.0\n",
      "torch 2.5.1+cpu\n",
      "cpu\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备数据"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T13:51:00.329766Z",
     "start_time": "2025-01-16T13:50:34.598101Z"
    }
   },
   "source": [
    "from sklearn.datasets import fetch_california_housing\n",
    "\n",
    "housing = fetch_california_housing(data_home='data')\n",
    "print(housing.DESCR)\n",
    "print(housing.data.shape)\n",
    "print(housing.target.shape)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".. _california_housing_dataset:\n",
      "\n",
      "California Housing dataset\n",
      "--------------------------\n",
      "\n",
      "**Data Set Characteristics:**\n",
      "\n",
      ":Number of Instances: 20640\n",
      "\n",
      ":Number of Attributes: 8 numeric, predictive attributes and the target\n",
      "\n",
      ":Attribute Information:\n",
      "    - MedInc        median income in block group\n",
      "    - HouseAge      median house age in block group\n",
      "    - AveRooms      average number of rooms per household\n",
      "    - AveBedrms     average number of bedrooms per household\n",
      "    - Population    block group population\n",
      "    - AveOccup      average number of household members\n",
      "    - Latitude      block group latitude\n",
      "    - Longitude     block group longitude\n",
      "\n",
      ":Missing Attribute Values: None\n",
      "\n",
      "This dataset was obtained from the StatLib repository.\n",
      "https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.html\n",
      "\n",
      "The target variable is the median house value for California districts,\n",
      "expressed in hundreds of thousands of dollars ($100,000).\n",
      "\n",
      "This dataset was derived from the 1990 U.S. census, using one row per census\n",
      "block group. A block group is the smallest geographical unit for which the U.S.\n",
      "Census Bureau publishes sample data (a block group typically has a population\n",
      "of 600 to 3,000 people).\n",
      "\n",
      "A household is a group of people residing within a home. Since the average\n",
      "number of rooms and bedrooms in this dataset are provided per household, these\n",
      "columns may take surprisingly large values for block groups with few households\n",
      "and many empty houses, such as vacation resorts.\n",
      "\n",
      "It can be downloaded/loaded using the\n",
      ":func:`sklearn.datasets.fetch_california_housing` function.\n",
      "\n",
      ".. rubric:: References\n",
      "\n",
      "- Pace, R. Kelley and Ronald Barry, Sparse Spatial Autoregressions,\n",
      "  Statistics and Probability Letters, 33 (1997) 291-297\n",
      "\n",
      "(20640, 8)\n",
      "(20640,)\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T13:51:12.088217Z",
     "start_time": "2025-01-16T13:51:12.082864Z"
    }
   },
   "source": [
    "# print(housing.data[0:5])\n",
    "import pprint  #打印的格式比较 好看\n",
    "\n",
    "pprint.pprint(housing.data[0:2])\n",
    "print('-'*50)\n",
    "pprint.pprint(housing.target[0:2])"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "array([[ 8.32520000e+00,  4.10000000e+01,  6.98412698e+00,\n",
      "         1.02380952e+00,  3.22000000e+02,  2.55555556e+00,\n",
      "         3.78800000e+01, -1.22230000e+02],\n",
      "       [ 8.30140000e+00,  2.10000000e+01,  6.23813708e+00,\n",
      "         9.71880492e-01,  2.40100000e+03,  2.10984183e+00,\n",
      "         3.78600000e+01, -1.22220000e+02]])\n",
      "--------------------------------------------------\n",
      "array([4.526, 3.585])\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T13:56:19.905613Z",
     "start_time": "2025-01-16T13:56:19.896104Z"
    }
   },
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "#拆分训练集和测试集，random_state是随机种子,同样的随机数种子，是为了得到同样的随机值\n",
    "# 第一次分割，75%训练集和25%验证集，第二次分割，把这75%的训练集再分成75%训练集和25%验证集\n",
    "x_train_all, x_test, y_train_all, y_test = train_test_split(\n",
    "    housing.data, housing.target, random_state = 7)\n",
    "x_train, x_valid, y_train, y_valid = train_test_split(\n",
    "    x_train_all, y_train_all, random_state = 11)\n",
    "# 训练集\n",
    "print(x_train.shape, y_train.shape)\n",
    "# 验证集\n",
    "print(x_valid.shape, y_valid.shape)\n",
    "# 测试集\n",
    "print(x_test.shape, y_test.shape)\n",
    "\n",
    "dataset_maps = {\n",
    "    \"train\": [x_train, y_train], #训练集\n",
    "    \"valid\": [x_valid, y_valid], #验证集\n",
    "    \"test\": [x_test, y_test], #测试集\n",
    "} #把3个数据集都放到字典中\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(11610, 8) (11610,)\n",
      "(3870, 8) (3870,)\n",
      "(5160, 8) (5160,)\n",
      "<class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "execution_count": 12
  },
  {
   "cell_type": "code",
   "source": [
    "type(x_train)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-01-16T13:54:20.665293Z",
     "start_time": "2025-01-16T13:54:20.659795Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.ndarray"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 7
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T13:54:34.966702Z",
     "start_time": "2025-01-16T13:54:34.959846Z"
    }
   },
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "\n",
    "\n",
    "scaler = StandardScaler() #标准化\n",
    "scaler.fit(x_train) #fit和fit_transform的区别，fit是计算均值和方差，fit_transform是先fit，然后transform"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "StandardScaler()"
      ],
      "text/html": [
       "<style>#sk-container-id-2 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-2 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-2 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-2 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-2 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-2 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-2 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>StandardScaler()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" checked><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>StandardScaler</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.preprocessing.StandardScaler.html\">?<span>Documentation for StandardScaler</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>StandardScaler()</pre></div> </div></div></div></div>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 9
  },
  {
   "cell_type": "code",
   "source": [
    "np.array(1).shape"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-01-16T13:54:39.184237Z",
     "start_time": "2025-01-16T13:54:39.180067Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 10
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 构建数据集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T13:58:02.045640Z",
     "start_time": "2025-01-16T13:58:01.997066Z"
    }
   },
   "source": [
    "#构建私有数据集，就需要用如下方式\n",
    "from torch.utils.data import Dataset\n",
    "\n",
    "class HousingDataset(Dataset):\n",
    "    def __init__(self, mode='train'):\n",
    "        self.x, self.y = dataset_maps[mode] #x,y都是ndarray类型,dataset_maps是一个字典，里面有3个数据集\n",
    "        self.x = torch.from_numpy(scaler.transform(self.x)).float() #from_numpy将NumPy数组转换成PyTorch张量,这里将覅他和transform分开写是为了与下面实例化相匹配\n",
    "        self.y = torch.from_numpy(self.y).float().reshape(-1, 1) #处理为多行1列的tensor类型,因为__getitem__切片时需要，模型输出的形状时（batch_size, 1），而此时的y是一维的（xxx,），所以需要reshape成（xxx,1）\n",
    "            \n",
    "    def __len__(self): #必须写\n",
    "        return len(self.x) #返回数据集的长度,0维的size\n",
    "    \n",
    "    def __getitem__(self, idx): #idx是索引，返回的是数据和标签，这里是一个样本。__getitem__ 方法是 PyTorch 的 Dataset 类的核心方法之一，它的存在是为了实现数据集的按索引访问功能。\n",
    "        return self.x[idx], self.y[idx]\n",
    "    \n",
    "#train_ds是dataset类型的数据，与前面例子的FashionMNIST类型一致\n",
    "train_ds = HousingDataset(\"train\")\n",
    "valid_ds = HousingDataset(\"valid\")\n",
    "test_ds = HousingDataset(\"test\")"
   ],
   "outputs": [],
   "execution_count": 14
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T13:58:03.871393Z",
     "start_time": "2025-01-16T13:58:03.865706Z"
    }
   },
   "cell_type": "code",
   "source": "type(train_ds)",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "__main__.HousingDataset"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 15
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T14:10:45.394162Z",
     "start_time": "2025-01-16T14:10:45.389143Z"
    }
   },
   "source": "train_ds[0]",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([ 0.8015,  0.2722, -0.1162, -0.2023, -0.5431, -0.0210, -0.5898, -0.0824]),\n",
       " tensor([3.2260]))"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 22
  },
  {
   "cell_type": "code",
   "source": "train_ds[0][0]",
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-01-16T14:10:56.537200Z",
     "start_time": "2025-01-16T14:10:56.532202Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([ 0.8015,  0.2722, -0.1162, -0.2023, -0.5431, -0.0210, -0.5898, -0.0824])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 24
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T14:11:08.684158Z",
     "start_time": "2025-01-16T14:11:08.678700Z"
    }
   },
   "cell_type": "code",
   "source": "train_ds[0][1]",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([3.2260])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 25
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T14:25:58.215096Z",
     "start_time": "2025-01-16T14:25:58.210498Z"
    }
   },
   "source": [
    "from torch.utils.data import DataLoader\n",
    "\n",
    "#放到DataLoader中的train_ds, valid_ds, test_ds都是dataset类型的数据\n",
    "batch_size = 16 #batch_size是可以调的超参数\n",
    "train_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True)\n",
    "val_loader = DataLoader(valid_ds, batch_size=batch_size, shuffle=False)\n",
    "test_loader = DataLoader(test_ds, batch_size=batch_size, shuffle=False)"
   ],
   "outputs": [],
   "execution_count": 27
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 定义模型"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T14:26:00.773387Z",
     "start_time": "2025-01-16T14:26:00.769546Z"
    }
   },
   "source": [
    "#回归模型我们只需要1个数，且回归最后一层不需要激活函数\n",
    "\n",
    "class NeuralNetwork(nn.Module):\n",
    "    def __init__(self, input_dim=8):  #input_dim=8表示输入特征的维度是8\n",
    "        super().__init__()\n",
    "        self.linear_relu_stack = nn.Sequential(\n",
    "            nn.Linear(input_dim, 30),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(30, 1)\n",
    "            )\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # x.shape [batch size, 8]\n",
    "        logits = self.linear_relu_stack(x)\n",
    "        # logits.shape [batch size, 1]\n",
    "        return logits"
   ],
   "outputs": [],
   "execution_count": 28
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T14:26:03.210785Z",
     "start_time": "2025-01-16T14:26:03.206366Z"
    }
   },
   "cell_type": "code",
   "source": "8*30+30+30*1+1",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "301"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 29
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 早停"
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T14:26:08.469609Z",
     "start_time": "2025-01-16T14:26:08.465585Z"
    }
   },
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience # 多少个step没有提升就停止训练，此时认为即将过拟合\n",
    "        self.min_delta = min_delta # 最小的提升幅度,就是准确率，\n",
    "        self.best_metric = -1  # 最好的指标，指标不可能为负数，所以初始化为-1，此时指标即为准确率\n",
    "        self.counter = 0  # 计数器，记录多少个step没有提升\n",
    "        \n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter \n",
    "            self.counter = 0\n",
    "        else: \n",
    "            self.counter += 1\n",
    "            \n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience\n"
   ],
   "outputs": [],
   "execution_count": 30
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T14:26:10.118448Z",
     "start_time": "2025-01-16T14:26:10.114041Z"
    }
   },
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "# 回归没有准确率\n",
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)         # 验证集损失\n",
    "        loss_list.append(loss.item())\n",
    "        \n",
    "    return np.mean(loss_list)\n"
   ],
   "outputs": [],
   "execution_count": 31
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T14:29:25.565775Z",
     "start_time": "2025-01-16T14:28:05.176484Z"
    }
   },
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "    \n",
    "    global_step = 0\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # training\n",
    "            for datas, labels in train_loader:#11610/16=726  725*100=72600\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas) #得到预测值\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    " \n",
    "                loss = loss.cpu().item() #转为cpu类型，item()是取值\n",
    "                # record\n",
    "                \n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"step\": global_step\n",
    "                })\n",
    "                \n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "\n",
    "                    # 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                        early_stop_callback(-val_loss) #根据验证集的损失来实现早停，因损失肯定是越来越小的，所以用负号表示\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                    \n",
    "                # udate step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "        \n",
    "    return record_dict\n",
    "        \n",
    "\n",
    "epoch = 100\n",
    "\n",
    "model = NeuralNetwork()\n",
    "\n",
    "# 1. 定义损失函数 采用MSE损失,均方误差\n",
    "loss_fct = nn.MSELoss()\n",
    "# 2. 定义优化器 采用SGD\n",
    "# Optimizers specified in the torch.optim package\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n",
    "\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=10, min_delta=1e-3)\n",
    "\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_loader)\n",
    "    )"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "  0%|          | 0/72600 [00:00<?, ?it/s]"
      ],
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "ea9383b233c94e5d8b24a4f4b07bdc29"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Early stop at epoch 84 / global_step 60984\n"
     ]
    }
   ],
   "execution_count": 33
  },
  {
   "cell_type": "code",
   "source": [
    "record"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-01-16T14:29:31.487317Z",
     "start_time": "2025-01-16T14:29:31.452276Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'train': [{'loss': 6.486412048339844, 'step': 0},\n",
       "  {'loss': 4.548095703125, 'step': 1},\n",
       "  {'loss': 6.816545009613037, 'step': 2},\n",
       "  {'loss': 4.251072883605957, 'step': 3},\n",
       "  {'loss': 4.356777191162109, 'step': 4},\n",
       "  {'loss': 3.5657286643981934, 'step': 5},\n",
       "  {'loss': 3.3267974853515625, 'step': 6},\n",
       "  {'loss': 4.462804317474365, 'step': 7},\n",
       "  {'loss': 5.452294826507568, 'step': 8},\n",
       "  {'loss': 4.748667240142822, 'step': 9},\n",
       "  {'loss': 3.595508098602295, 'step': 10},\n",
       "  {'loss': 4.006546497344971, 'step': 11},\n",
       "  {'loss': 3.4619507789611816, 'step': 12},\n",
       "  {'loss': 3.096759557723999, 'step': 13},\n",
       "  {'loss': 3.435666561126709, 'step': 14},\n",
       "  {'loss': 2.447559118270874, 'step': 15},\n",
       "  {'loss': 2.6508851051330566, 'step': 16},\n",
       "  {'loss': 2.4952235221862793, 'step': 17},\n",
       "  {'loss': 3.4854657649993896, 'step': 18},\n",
       "  {'loss': 3.5181846618652344, 'step': 19},\n",
       "  {'loss': 1.483536720275879, 'step': 20},\n",
       "  {'loss': 1.1511151790618896, 'step': 21},\n",
       "  {'loss': 3.6751785278320312, 'step': 22},\n",
       "  {'loss': 1.1527575254440308, 'step': 23},\n",
       "  {'loss': 1.9682093858718872, 'step': 24},\n",
       "  {'loss': 0.8024883270263672, 'step': 25},\n",
       "  {'loss': 1.332409381866455, 'step': 26},\n",
       "  {'loss': 0.8613170385360718, 'step': 27},\n",
       "  {'loss': 0.6724238395690918, 'step': 28},\n",
       "  {'loss': 0.5138770937919617, 'step': 29},\n",
       "  {'loss': 0.5209949016571045, 'step': 30},\n",
       "  {'loss': 1.1760345697402954, 'step': 31},\n",
       "  {'loss': 0.47243010997772217, 'step': 32},\n",
       "  {'loss': 2.1288368701934814, 'step': 33},\n",
       "  {'loss': 46.057823181152344, 'step': 34},\n",
       "  {'loss': 0.9248675107955933, 'step': 35},\n",
       "  {'loss': 0.9916422367095947, 'step': 36},\n",
       "  {'loss': 1.171413779258728, 'step': 37},\n",
       "  {'loss': 1.9074733257293701, 'step': 38},\n",
       "  {'loss': 2.01922869682312, 'step': 39},\n",
       "  {'loss': 0.5355433821678162, 'step': 40},\n",
       "  {'loss': 1.0111150741577148, 'step': 41},\n",
       "  {'loss': 1.3461130857467651, 'step': 42},\n",
       "  {'loss': 0.7376141548156738, 'step': 43},\n",
       "  {'loss': 0.47349292039871216, 'step': 44},\n",
       "  {'loss': 0.5651824474334717, 'step': 45},\n",
       "  {'loss': 1.908300518989563, 'step': 46},\n",
       "  {'loss': 1.9045896530151367, 'step': 47},\n",
       "  {'loss': 2.5950870513916016, 'step': 48},\n",
       "  {'loss': 0.3407626152038574, 'step': 49},\n",
       "  {'loss': 1.1861882209777832, 'step': 50},\n",
       "  {'loss': 2.752779483795166, 'step': 51},\n",
       "  {'loss': 1.4013478755950928, 'step': 52},\n",
       "  {'loss': 1.4125854969024658, 'step': 53},\n",
       "  {'loss': 1.3551338911056519, 'step': 54},\n",
       "  {'loss': 1.0904297828674316, 'step': 55},\n",
       "  {'loss': 1.9058586359024048, 'step': 56},\n",
       "  {'loss': 1.9797353744506836, 'step': 57},\n",
       "  {'loss': 1.1870135068893433, 'step': 58},\n",
       "  {'loss': 0.9923363924026489, 'step': 59},\n",
       "  {'loss': 1.9795194864273071, 'step': 60},\n",
       "  {'loss': 0.8886715769767761, 'step': 61},\n",
       "  {'loss': 12.413069725036621, 'step': 62},\n",
       "  {'loss': 0.9084048867225647, 'step': 63},\n",
       "  {'loss': 1.049766182899475, 'step': 64},\n",
       "  {'loss': 0.5224167108535767, 'step': 65},\n",
       "  {'loss': 0.4851062595844269, 'step': 66},\n",
       "  {'loss': 0.7361374497413635, 'step': 67},\n",
       "  {'loss': 0.5047112107276917, 'step': 68},\n",
       "  {'loss': 0.6366775035858154, 'step': 69},\n",
       "  {'loss': 0.25237512588500977, 'step': 70},\n",
       "  {'loss': 0.6859531998634338, 'step': 71},\n",
       "  {'loss': 0.3307534456253052, 'step': 72},\n",
       "  {'loss': 1.1481393575668335, 'step': 73},\n",
       "  {'loss': 0.6029646396636963, 'step': 74},\n",
       "  {'loss': 0.8067167401313782, 'step': 75},\n",
       "  {'loss': 1.0809942483901978, 'step': 76},\n",
       "  {'loss': 1.3826775550842285, 'step': 77},\n",
       "  {'loss': 0.5083439350128174, 'step': 78},\n",
       "  {'loss': 0.39451852440834045, 'step': 79},\n",
       "  {'loss': 0.5941134691238403, 'step': 80},\n",
       "  {'loss': 1.2069625854492188, 'step': 81},\n",
       "  {'loss': 0.8934943675994873, 'step': 82},\n",
       "  {'loss': 0.5961492657661438, 'step': 83},\n",
       "  {'loss': 0.5617584586143494, 'step': 84},\n",
       "  {'loss': 0.6496630907058716, 'step': 85},\n",
       "  {'loss': 0.5444587469100952, 'step': 86},\n",
       "  {'loss': 0.3853098154067993, 'step': 87},\n",
       "  {'loss': 0.5570971965789795, 'step': 88},\n",
       "  {'loss': 0.908789873123169, 'step': 89},\n",
       "  {'loss': 0.4856981039047241, 'step': 90},\n",
       "  {'loss': 0.6319162249565125, 'step': 91},\n",
       "  {'loss': 0.43717581033706665, 'step': 92},\n",
       "  {'loss': 0.9243928790092468, 'step': 93},\n",
       "  {'loss': 0.7656753659248352, 'step': 94},\n",
       "  {'loss': 0.7175837159156799, 'step': 95},\n",
       "  {'loss': 1.7839329242706299, 'step': 96},\n",
       "  {'loss': 1.0268166065216064, 'step': 97},\n",
       "  {'loss': 0.5409560799598694, 'step': 98},\n",
       "  {'loss': 0.7460716962814331, 'step': 99},\n",
       "  {'loss': 0.20640361309051514, 'step': 100},\n",
       "  {'loss': 0.8368129730224609, 'step': 101},\n",
       "  {'loss': 0.5476335883140564, 'step': 102},\n",
       "  {'loss': 0.23592835664749146, 'step': 103},\n",
       "  {'loss': 0.5818709135055542, 'step': 104},\n",
       "  {'loss': 0.9197301268577576, 'step': 105},\n",
       "  {'loss': 0.5534376502037048, 'step': 106},\n",
       "  {'loss': 0.9940187335014343, 'step': 107},\n",
       "  {'loss': 0.29867058992385864, 'step': 108},\n",
       "  {'loss': 0.8698898553848267, 'step': 109},\n",
       "  {'loss': 1.1864466667175293, 'step': 110},\n",
       "  {'loss': 0.911737322807312, 'step': 111},\n",
       "  {'loss': 0.7387936115264893, 'step': 112},\n",
       "  {'loss': 0.32415953278541565, 'step': 113},\n",
       "  {'loss': 0.6728917956352234, 'step': 114},\n",
       "  {'loss': 0.35674822330474854, 'step': 115},\n",
       "  {'loss': 0.40546584129333496, 'step': 116},\n",
       "  {'loss': 0.9450956583023071, 'step': 117},\n",
       "  {'loss': 0.6845486164093018, 'step': 118},\n",
       "  {'loss': 0.9377390146255493, 'step': 119},\n",
       "  {'loss': 0.34188583493232727, 'step': 120},\n",
       "  {'loss': 0.334715873003006, 'step': 121},\n",
       "  {'loss': 0.7298887372016907, 'step': 122},\n",
       "  {'loss': 1.1379845142364502, 'step': 123},\n",
       "  {'loss': 0.6280373930931091, 'step': 124},\n",
       "  {'loss': 0.5409371852874756, 'step': 125},\n",
       "  {'loss': 0.5299467444419861, 'step': 126},\n",
       "  {'loss': 1.5430629253387451, 'step': 127},\n",
       "  {'loss': 0.37523189187049866, 'step': 128},\n",
       "  {'loss': 0.6581236124038696, 'step': 129},\n",
       "  {'loss': 0.5849034786224365, 'step': 130},\n",
       "  {'loss': 0.4973418712615967, 'step': 131},\n",
       "  {'loss': 0.8729873895645142, 'step': 132},\n",
       "  {'loss': 0.5022962093353271, 'step': 133},\n",
       "  {'loss': 0.5493314266204834, 'step': 134},\n",
       "  {'loss': 0.4912675619125366, 'step': 135},\n",
       "  {'loss': 0.2971954345703125, 'step': 136},\n",
       "  {'loss': 0.41990959644317627, 'step': 137},\n",
       "  {'loss': 0.9464071989059448, 'step': 138},\n",
       "  {'loss': 0.7423722147941589, 'step': 139},\n",
       "  {'loss': 0.22471821308135986, 'step': 140},\n",
       "  {'loss': 0.6044372320175171, 'step': 141},\n",
       "  {'loss': 0.27935007214546204, 'step': 142},\n",
       "  {'loss': 0.47255316376686096, 'step': 143},\n",
       "  {'loss': 0.3701398968696594, 'step': 144},\n",
       "  {'loss': 0.7378968000411987, 'step': 145},\n",
       "  {'loss': 1.0224119424819946, 'step': 146},\n",
       "  {'loss': 0.7564852833747864, 'step': 147},\n",
       "  {'loss': 0.6937706470489502, 'step': 148},\n",
       "  {'loss': 0.3030548393726349, 'step': 149},\n",
       "  {'loss': 0.7313036322593689, 'step': 150},\n",
       "  {'loss': 0.39084550738334656, 'step': 151},\n",
       "  {'loss': 1.0512710809707642, 'step': 152},\n",
       "  {'loss': 1.153499960899353, 'step': 153},\n",
       "  {'loss': 0.5830352902412415, 'step': 154},\n",
       "  {'loss': 0.6511121988296509, 'step': 155},\n",
       "  {'loss': 0.2448088377714157, 'step': 156},\n",
       "  {'loss': 1.1863948106765747, 'step': 157},\n",
       "  {'loss': 0.9537224173545837, 'step': 158},\n",
       "  {'loss': 0.3592022955417633, 'step': 159},\n",
       "  {'loss': 0.6440856456756592, 'step': 160},\n",
       "  {'loss': 0.44170859456062317, 'step': 161},\n",
       "  {'loss': 0.829910397529602, 'step': 162},\n",
       "  {'loss': 0.6639597415924072, 'step': 163},\n",
       "  {'loss': 0.692967414855957, 'step': 164},\n",
       "  {'loss': 0.45962703227996826, 'step': 165},\n",
       "  {'loss': 0.44316965341567993, 'step': 166},\n",
       "  {'loss': 1.5790902376174927, 'step': 167},\n",
       "  {'loss': 1.171185851097107, 'step': 168},\n",
       "  {'loss': 0.5522383451461792, 'step': 169},\n",
       "  {'loss': 0.37213262915611267, 'step': 170},\n",
       "  {'loss': 0.24193206429481506, 'step': 171},\n",
       "  {'loss': 0.4381629228591919, 'step': 172},\n",
       "  {'loss': 0.8038470149040222, 'step': 173},\n",
       "  {'loss': 0.4738026261329651, 'step': 174},\n",
       "  {'loss': 0.9425644874572754, 'step': 175},\n",
       "  {'loss': 0.15975211560726166, 'step': 176},\n",
       "  {'loss': 0.3365466892719269, 'step': 177},\n",
       "  {'loss': 0.3073195815086365, 'step': 178},\n",
       "  {'loss': 0.6843123435974121, 'step': 179},\n",
       "  {'loss': 0.9065957069396973, 'step': 180},\n",
       "  {'loss': 1.037705659866333, 'step': 181},\n",
       "  {'loss': 0.4668339788913727, 'step': 182},\n",
       "  {'loss': 0.2520720064640045, 'step': 183},\n",
       "  {'loss': 0.4859563708305359, 'step': 184},\n",
       "  {'loss': 0.4711943566799164, 'step': 185},\n",
       "  {'loss': 0.8434975147247314, 'step': 186},\n",
       "  {'loss': 0.37308791279792786, 'step': 187},\n",
       "  {'loss': 0.5593916177749634, 'step': 188},\n",
       "  {'loss': 0.3245829641819, 'step': 189},\n",
       "  {'loss': 0.2328174114227295, 'step': 190},\n",
       "  {'loss': 0.4121931195259094, 'step': 191},\n",
       "  {'loss': 0.543073832988739, 'step': 192},\n",
       "  {'loss': 0.3555266857147217, 'step': 193},\n",
       "  {'loss': 0.7835736274719238, 'step': 194},\n",
       "  {'loss': 0.29941120743751526, 'step': 195},\n",
       "  {'loss': 0.2866973876953125, 'step': 196},\n",
       "  {'loss': 0.4021536707878113, 'step': 197},\n",
       "  {'loss': 0.1647317260503769, 'step': 198},\n",
       "  {'loss': 0.39275938272476196, 'step': 199},\n",
       "  {'loss': 1.2454068660736084, 'step': 200},\n",
       "  {'loss': 0.23212286829948425, 'step': 201},\n",
       "  {'loss': 0.30910953879356384, 'step': 202},\n",
       "  {'loss': 0.49981462955474854, 'step': 203},\n",
       "  {'loss': 0.41000890731811523, 'step': 204},\n",
       "  {'loss': 0.22927898168563843, 'step': 205},\n",
       "  {'loss': 0.9638314247131348, 'step': 206},\n",
       "  {'loss': 1.168518304824829, 'step': 207},\n",
       "  {'loss': 0.6891521215438843, 'step': 208},\n",
       "  {'loss': 0.45425644516944885, 'step': 209},\n",
       "  {'loss': 0.6919563412666321, 'step': 210},\n",
       "  {'loss': 0.2608695924282074, 'step': 211},\n",
       "  {'loss': 0.32886993885040283, 'step': 212},\n",
       "  {'loss': 0.460952490568161, 'step': 213},\n",
       "  {'loss': 0.30260565876960754, 'step': 214},\n",
       "  {'loss': 0.309940904378891, 'step': 215},\n",
       "  {'loss': 0.8181538581848145, 'step': 216},\n",
       "  {'loss': 0.455377459526062, 'step': 217},\n",
       "  {'loss': 0.9367126226425171, 'step': 218},\n",
       "  {'loss': 1.2217506170272827, 'step': 219},\n",
       "  {'loss': 1.2664618492126465, 'step': 220},\n",
       "  {'loss': 0.4501582682132721, 'step': 221},\n",
       "  {'loss': 0.3215727210044861, 'step': 222},\n",
       "  {'loss': 0.28808027505874634, 'step': 223},\n",
       "  {'loss': 0.1799546182155609, 'step': 224},\n",
       "  {'loss': 0.7297160625457764, 'step': 225},\n",
       "  {'loss': 0.3038537800312042, 'step': 226},\n",
       "  {'loss': 0.2824589014053345, 'step': 227},\n",
       "  {'loss': 0.9092711210250854, 'step': 228},\n",
       "  {'loss': 0.8395689129829407, 'step': 229},\n",
       "  {'loss': 0.7486065626144409, 'step': 230},\n",
       "  {'loss': 0.5705505013465881, 'step': 231},\n",
       "  {'loss': 0.6596646308898926, 'step': 232},\n",
       "  {'loss': 0.1654503494501114, 'step': 233},\n",
       "  {'loss': 0.4548775553703308, 'step': 234},\n",
       "  {'loss': 0.3111678957939148, 'step': 235},\n",
       "  {'loss': 0.5354838967323303, 'step': 236},\n",
       "  {'loss': 0.5378715395927429, 'step': 237},\n",
       "  {'loss': 0.575325071811676, 'step': 238},\n",
       "  {'loss': 0.17697453498840332, 'step': 239},\n",
       "  {'loss': 0.6142268180847168, 'step': 240},\n",
       "  {'loss': 0.30118924379348755, 'step': 241},\n",
       "  {'loss': 0.45725753903388977, 'step': 242},\n",
       "  {'loss': 0.7080118656158447, 'step': 243},\n",
       "  {'loss': 0.1846177875995636, 'step': 244},\n",
       "  {'loss': 0.7361438274383545, 'step': 245},\n",
       "  {'loss': 0.8882074356079102, 'step': 246},\n",
       "  {'loss': 0.430996835231781, 'step': 247},\n",
       "  {'loss': 0.1927940398454666, 'step': 248},\n",
       "  {'loss': 0.4484013020992279, 'step': 249},\n",
       "  {'loss': 0.9628889560699463, 'step': 250},\n",
       "  {'loss': 0.4448087513446808, 'step': 251},\n",
       "  {'loss': 0.26511305570602417, 'step': 252},\n",
       "  {'loss': 0.4791402816772461, 'step': 253},\n",
       "  {'loss': 0.7473151087760925, 'step': 254},\n",
       "  {'loss': 0.31894490122795105, 'step': 255},\n",
       "  {'loss': 0.1848127841949463, 'step': 256},\n",
       "  {'loss': 0.27575069665908813, 'step': 257},\n",
       "  {'loss': 0.3995361030101776, 'step': 258},\n",
       "  {'loss': 0.8189515471458435, 'step': 259},\n",
       "  {'loss': 1.2195563316345215, 'step': 260},\n",
       "  {'loss': 0.29487302899360657, 'step': 261},\n",
       "  {'loss': 0.34048232436180115, 'step': 262},\n",
       "  {'loss': 0.8229047060012817, 'step': 263},\n",
       "  {'loss': 0.3861418068408966, 'step': 264},\n",
       "  {'loss': 0.21963883936405182, 'step': 265},\n",
       "  {'loss': 0.5320175886154175, 'step': 266},\n",
       "  {'loss': 0.27792686223983765, 'step': 267},\n",
       "  {'loss': 0.5373734831809998, 'step': 268},\n",
       "  {'loss': 0.2818380296230316, 'step': 269},\n",
       "  {'loss': 0.9726592302322388, 'step': 270},\n",
       "  {'loss': 0.7109344005584717, 'step': 271},\n",
       "  {'loss': 0.9096727967262268, 'step': 272},\n",
       "  {'loss': 0.38265517354011536, 'step': 273},\n",
       "  {'loss': 0.695609986782074, 'step': 274},\n",
       "  {'loss': 1.2957743406295776, 'step': 275},\n",
       "  {'loss': 0.46655136346817017, 'step': 276},\n",
       "  {'loss': 0.966677188873291, 'step': 277},\n",
       "  {'loss': 0.23604610562324524, 'step': 278},\n",
       "  {'loss': 0.6067392826080322, 'step': 279},\n",
       "  {'loss': 0.5355483293533325, 'step': 280},\n",
       "  {'loss': 0.5997549295425415, 'step': 281},\n",
       "  {'loss': 1.1937509775161743, 'step': 282},\n",
       "  {'loss': 0.1612853854894638, 'step': 283},\n",
       "  {'loss': 0.46227502822875977, 'step': 284},\n",
       "  {'loss': 0.342378705739975, 'step': 285},\n",
       "  {'loss': 0.818207859992981, 'step': 286},\n",
       "  {'loss': 0.5379908084869385, 'step': 287},\n",
       "  {'loss': 0.1418371945619583, 'step': 288},\n",
       "  {'loss': 0.6030550599098206, 'step': 289},\n",
       "  {'loss': 0.30766060948371887, 'step': 290},\n",
       "  {'loss': 0.3088756501674652, 'step': 291},\n",
       "  {'loss': 0.2432117760181427, 'step': 292},\n",
       "  {'loss': 0.567956805229187, 'step': 293},\n",
       "  {'loss': 0.1754644364118576, 'step': 294},\n",
       "  {'loss': 0.21558496356010437, 'step': 295},\n",
       "  {'loss': 0.3712374269962311, 'step': 296},\n",
       "  {'loss': 0.1861390322446823, 'step': 297},\n",
       "  {'loss': 0.43715810775756836, 'step': 298},\n",
       "  {'loss': 0.250246524810791, 'step': 299},\n",
       "  {'loss': 0.2750554084777832, 'step': 300},\n",
       "  {'loss': 0.9723025560379028, 'step': 301},\n",
       "  {'loss': 0.4230172634124756, 'step': 302},\n",
       "  {'loss': 0.2986152172088623, 'step': 303},\n",
       "  {'loss': 1.051708698272705, 'step': 304},\n",
       "  {'loss': 0.5449401140213013, 'step': 305},\n",
       "  {'loss': 0.9193158149719238, 'step': 306},\n",
       "  {'loss': 0.37157949805259705, 'step': 307},\n",
       "  {'loss': 0.33848580718040466, 'step': 308},\n",
       "  {'loss': 0.7064727544784546, 'step': 309},\n",
       "  {'loss': 0.8961547613143921, 'step': 310},\n",
       "  {'loss': 0.37823012471199036, 'step': 311},\n",
       "  {'loss': 0.8439241647720337, 'step': 312},\n",
       "  {'loss': 0.34433239698410034, 'step': 313},\n",
       "  {'loss': 0.3355857729911804, 'step': 314},\n",
       "  {'loss': 1.0940444469451904, 'step': 315},\n",
       "  {'loss': 0.3956507742404938, 'step': 316},\n",
       "  {'loss': 0.6386028528213501, 'step': 317},\n",
       "  {'loss': 0.27753984928131104, 'step': 318},\n",
       "  {'loss': 0.550627589225769, 'step': 319},\n",
       "  {'loss': 0.359782338142395, 'step': 320},\n",
       "  {'loss': 0.26357680559158325, 'step': 321},\n",
       "  {'loss': 0.6019083261489868, 'step': 322},\n",
       "  {'loss': 0.261974573135376, 'step': 323},\n",
       "  {'loss': 0.1924230456352234, 'step': 324},\n",
       "  {'loss': 0.30264097452163696, 'step': 325},\n",
       "  {'loss': 0.28511953353881836, 'step': 326},\n",
       "  {'loss': 0.8814232349395752, 'step': 327},\n",
       "  {'loss': 0.4600985050201416, 'step': 328},\n",
       "  {'loss': 0.463966429233551, 'step': 329},\n",
       "  {'loss': 0.30166029930114746, 'step': 330},\n",
       "  {'loss': 0.6312171220779419, 'step': 331},\n",
       "  {'loss': 0.1460600048303604, 'step': 332},\n",
       "  {'loss': 3.0517241954803467, 'step': 333},\n",
       "  {'loss': 0.40725886821746826, 'step': 334},\n",
       "  {'loss': 0.26068952679634094, 'step': 335},\n",
       "  {'loss': 0.26238852739334106, 'step': 336},\n",
       "  {'loss': 0.7762588858604431, 'step': 337},\n",
       "  {'loss': 0.65057373046875, 'step': 338},\n",
       "  {'loss': 0.3581137955188751, 'step': 339},\n",
       "  {'loss': 0.37347978353500366, 'step': 340},\n",
       "  {'loss': 0.20488375425338745, 'step': 341},\n",
       "  {'loss': 0.9468446969985962, 'step': 342},\n",
       "  {'loss': 0.3010158836841583, 'step': 343},\n",
       "  {'loss': 0.8074026107788086, 'step': 344},\n",
       "  {'loss': 1.0337399244308472, 'step': 345},\n",
       "  {'loss': 0.5476281642913818, 'step': 346},\n",
       "  {'loss': 0.34485188126564026, 'step': 347},\n",
       "  {'loss': 0.3035852015018463, 'step': 348},\n",
       "  {'loss': 0.17700457572937012, 'step': 349},\n",
       "  {'loss': 0.3402481973171234, 'step': 350},\n",
       "  {'loss': 0.3098145127296448, 'step': 351},\n",
       "  {'loss': 0.7669840455055237, 'step': 352},\n",
       "  {'loss': 0.15040570497512817, 'step': 353},\n",
       "  {'loss': 1.3246511220932007, 'step': 354},\n",
       "  {'loss': 0.443298876285553, 'step': 355},\n",
       "  {'loss': 0.7387576103210449, 'step': 356},\n",
       "  {'loss': 0.7273866534233093, 'step': 357},\n",
       "  {'loss': 0.3216779828071594, 'step': 358},\n",
       "  {'loss': 0.6858131885528564, 'step': 359},\n",
       "  {'loss': 0.39607155323028564, 'step': 360},\n",
       "  {'loss': 0.4755396842956543, 'step': 361},\n",
       "  {'loss': 0.49491211771965027, 'step': 362},\n",
       "  {'loss': 0.18988259136676788, 'step': 363},\n",
       "  {'loss': 0.17159989476203918, 'step': 364},\n",
       "  {'loss': 0.4653638005256653, 'step': 365},\n",
       "  {'loss': 0.26230013370513916, 'step': 366},\n",
       "  {'loss': 0.28817206621170044, 'step': 367},\n",
       "  {'loss': 0.1679624319076538, 'step': 368},\n",
       "  {'loss': 0.18442612886428833, 'step': 369},\n",
       "  {'loss': 0.23466068506240845, 'step': 370},\n",
       "  {'loss': 0.24452713131904602, 'step': 371},\n",
       "  {'loss': 0.21486598253250122, 'step': 372},\n",
       "  {'loss': 0.1851542592048645, 'step': 373},\n",
       "  {'loss': 0.8444473147392273, 'step': 374},\n",
       "  {'loss': 0.2688944339752197, 'step': 375},\n",
       "  {'loss': 0.44598156213760376, 'step': 376},\n",
       "  {'loss': 0.4962649345397949, 'step': 377},\n",
       "  {'loss': 0.24108783900737762, 'step': 378},\n",
       "  {'loss': 0.36712509393692017, 'step': 379},\n",
       "  {'loss': 0.21571633219718933, 'step': 380},\n",
       "  {'loss': 0.2622652053833008, 'step': 381},\n",
       "  {'loss': 0.3643219769001007, 'step': 382},\n",
       "  {'loss': 1.3512126207351685, 'step': 383},\n",
       "  {'loss': 0.46703892946243286, 'step': 384},\n",
       "  {'loss': 0.23491224646568298, 'step': 385},\n",
       "  {'loss': 0.27142539620399475, 'step': 386},\n",
       "  {'loss': 0.13692741096019745, 'step': 387},\n",
       "  {'loss': 1.3124971389770508, 'step': 388},\n",
       "  {'loss': 0.484186589717865, 'step': 389},\n",
       "  {'loss': 0.37375134229660034, 'step': 390},\n",
       "  {'loss': 1.0078929662704468, 'step': 391},\n",
       "  {'loss': 0.2509879767894745, 'step': 392},\n",
       "  {'loss': 0.5145159363746643, 'step': 393},\n",
       "  {'loss': 0.2678808271884918, 'step': 394},\n",
       "  {'loss': 0.3304765522480011, 'step': 395},\n",
       "  {'loss': 0.5873590707778931, 'step': 396},\n",
       "  {'loss': 0.2699144780635834, 'step': 397},\n",
       "  {'loss': 0.24377605319023132, 'step': 398},\n",
       "  {'loss': 0.11039312183856964, 'step': 399},\n",
       "  {'loss': 0.6751980185508728, 'step': 400},\n",
       "  {'loss': 0.7601803541183472, 'step': 401},\n",
       "  {'loss': 0.3195769488811493, 'step': 402},\n",
       "  {'loss': 0.3661714792251587, 'step': 403},\n",
       "  {'loss': 0.8097559213638306, 'step': 404},\n",
       "  {'loss': 0.39773473143577576, 'step': 405},\n",
       "  {'loss': 0.18376049399375916, 'step': 406},\n",
       "  {'loss': 0.5532466173171997, 'step': 407},\n",
       "  {'loss': 0.6508378386497498, 'step': 408},\n",
       "  {'loss': 0.6489591598510742, 'step': 409},\n",
       "  {'loss': 0.6092151999473572, 'step': 410},\n",
       "  {'loss': 0.2404986470937729, 'step': 411},\n",
       "  {'loss': 0.3477514982223511, 'step': 412},\n",
       "  {'loss': 0.6944171190261841, 'step': 413},\n",
       "  {'loss': 0.2642453908920288, 'step': 414},\n",
       "  {'loss': 0.2694931924343109, 'step': 415},\n",
       "  {'loss': 0.43359634280204773, 'step': 416},\n",
       "  {'loss': 1.0904784202575684, 'step': 417},\n",
       "  {'loss': 0.13464868068695068, 'step': 418},\n",
       "  {'loss': 1.1919653415679932, 'step': 419},\n",
       "  {'loss': 0.40575820207595825, 'step': 420},\n",
       "  {'loss': 0.5164685249328613, 'step': 421},\n",
       "  {'loss': 0.28689542412757874, 'step': 422},\n",
       "  {'loss': 0.6038964986801147, 'step': 423},\n",
       "  {'loss': 0.40909698605537415, 'step': 424},\n",
       "  {'loss': 0.7957658767700195, 'step': 425},\n",
       "  {'loss': 0.6352195143699646, 'step': 426},\n",
       "  {'loss': 0.3373948037624359, 'step': 427},\n",
       "  {'loss': 0.26410573720932007, 'step': 428},\n",
       "  {'loss': 0.7716580033302307, 'step': 429},\n",
       "  {'loss': 0.4665391147136688, 'step': 430},\n",
       "  {'loss': 0.5189558267593384, 'step': 431},\n",
       "  {'loss': 0.5376269221305847, 'step': 432},\n",
       "  {'loss': 0.455801784992218, 'step': 433},\n",
       "  {'loss': 0.2711528539657593, 'step': 434},\n",
       "  {'loss': 1.2248376607894897, 'step': 435},\n",
       "  {'loss': 0.7284162044525146, 'step': 436},\n",
       "  {'loss': 0.24975408613681793, 'step': 437},\n",
       "  {'loss': 0.677465558052063, 'step': 438},\n",
       "  {'loss': 0.4252638816833496, 'step': 439},\n",
       "  {'loss': 1.5191168785095215, 'step': 440},\n",
       "  {'loss': 0.3019251823425293, 'step': 441},\n",
       "  {'loss': 0.3330758512020111, 'step': 442},\n",
       "  {'loss': 0.4608006775379181, 'step': 443},\n",
       "  {'loss': 0.8759182691574097, 'step': 444},\n",
       "  {'loss': 0.14475250244140625, 'step': 445},\n",
       "  {'loss': 0.34874314069747925, 'step': 446},\n",
       "  {'loss': 0.5975480079650879, 'step': 447},\n",
       "  {'loss': 0.7541627287864685, 'step': 448},\n",
       "  {'loss': 0.5753613114356995, 'step': 449},\n",
       "  {'loss': 0.26306286454200745, 'step': 450},\n",
       "  {'loss': 0.5806082487106323, 'step': 451},\n",
       "  {'loss': 0.18265552818775177, 'step': 452},\n",
       "  {'loss': 0.24272793531417847, 'step': 453},\n",
       "  {'loss': 0.39681416749954224, 'step': 454},\n",
       "  {'loss': 0.2803576588630676, 'step': 455},\n",
       "  {'loss': 0.18562717735767365, 'step': 456},\n",
       "  {'loss': 0.29509565234184265, 'step': 457},\n",
       "  {'loss': 0.3741195797920227, 'step': 458},\n",
       "  {'loss': 0.5125782489776611, 'step': 459},\n",
       "  {'loss': 0.39344608783721924, 'step': 460},\n",
       "  {'loss': 0.3714560568332672, 'step': 461},\n",
       "  {'loss': 0.3299447000026703, 'step': 462},\n",
       "  {'loss': 0.995194673538208, 'step': 463},\n",
       "  {'loss': 0.40947964787483215, 'step': 464},\n",
       "  {'loss': 0.5827612280845642, 'step': 465},\n",
       "  {'loss': 0.17131787538528442, 'step': 466},\n",
       "  {'loss': 0.24269790947437286, 'step': 467},\n",
       "  {'loss': 0.6938389539718628, 'step': 468},\n",
       "  {'loss': 0.5054202675819397, 'step': 469},\n",
       "  {'loss': 0.5021768808364868, 'step': 470},\n",
       "  {'loss': 0.26005297899246216, 'step': 471},\n",
       "  {'loss': 0.28474482893943787, 'step': 472},\n",
       "  {'loss': 0.6187103390693665, 'step': 473},\n",
       "  {'loss': 0.7158701419830322, 'step': 474},\n",
       "  {'loss': 0.3881073296070099, 'step': 475},\n",
       "  {'loss': 0.36912763118743896, 'step': 476},\n",
       "  {'loss': 0.6382364630699158, 'step': 477},\n",
       "  {'loss': 0.37532827258110046, 'step': 478},\n",
       "  {'loss': 0.3368605673313141, 'step': 479},\n",
       "  {'loss': 0.21703872084617615, 'step': 480},\n",
       "  {'loss': 0.21293382346630096, 'step': 481},\n",
       "  {'loss': 0.3556658625602722, 'step': 482},\n",
       "  {'loss': 0.3360384404659271, 'step': 483},\n",
       "  {'loss': 1.2498834133148193, 'step': 484},\n",
       "  {'loss': 0.9151362776756287, 'step': 485},\n",
       "  {'loss': 0.47473782300949097, 'step': 486},\n",
       "  {'loss': 0.32049790024757385, 'step': 487},\n",
       "  {'loss': 0.32994380593299866, 'step': 488},\n",
       "  {'loss': 0.23518991470336914, 'step': 489},\n",
       "  {'loss': 0.37123483419418335, 'step': 490},\n",
       "  {'loss': 0.6399737000465393, 'step': 491},\n",
       "  {'loss': 0.3810643255710602, 'step': 492},\n",
       "  {'loss': 0.36100760102272034, 'step': 493},\n",
       "  {'loss': 0.6194499731063843, 'step': 494},\n",
       "  {'loss': 0.4750310182571411, 'step': 495},\n",
       "  {'loss': 0.24306628108024597, 'step': 496},\n",
       "  {'loss': 0.24475960433483124, 'step': 497},\n",
       "  {'loss': 0.6519744396209717, 'step': 498},\n",
       "  {'loss': 0.2527226507663727, 'step': 499},\n",
       "  {'loss': 0.343373566865921, 'step': 500},\n",
       "  {'loss': 0.3316026031970978, 'step': 501},\n",
       "  {'loss': 0.6767128109931946, 'step': 502},\n",
       "  {'loss': 0.2604411542415619, 'step': 503},\n",
       "  {'loss': 0.5186160206794739, 'step': 504},\n",
       "  {'loss': 1.434818983078003, 'step': 505},\n",
       "  {'loss': 0.33144423365592957, 'step': 506},\n",
       "  {'loss': 0.3722894787788391, 'step': 507},\n",
       "  {'loss': 0.7544374465942383, 'step': 508},\n",
       "  {'loss': 0.24190931022167206, 'step': 509},\n",
       "  {'loss': 0.2754826545715332, 'step': 510},\n",
       "  {'loss': 0.27640295028686523, 'step': 511},\n",
       "  {'loss': 0.262356698513031, 'step': 512},\n",
       "  {'loss': 0.31746065616607666, 'step': 513},\n",
       "  {'loss': 0.8685972094535828, 'step': 514},\n",
       "  {'loss': 0.25300437211990356, 'step': 515},\n",
       "  {'loss': 0.6807591915130615, 'step': 516},\n",
       "  {'loss': 0.2841933071613312, 'step': 517},\n",
       "  {'loss': 0.31592828035354614, 'step': 518},\n",
       "  {'loss': 0.2951905131340027, 'step': 519},\n",
       "  {'loss': 0.20974081754684448, 'step': 520},\n",
       "  {'loss': 0.31436604261398315, 'step': 521},\n",
       "  {'loss': 0.982292115688324, 'step': 522},\n",
       "  {'loss': 0.16178730130195618, 'step': 523},\n",
       "  {'loss': 0.31192296743392944, 'step': 524},\n",
       "  {'loss': 0.8952710628509521, 'step': 525},\n",
       "  {'loss': 0.41053295135498047, 'step': 526},\n",
       "  {'loss': 0.2234450876712799, 'step': 527},\n",
       "  {'loss': 0.2784183621406555, 'step': 528},\n",
       "  {'loss': 0.32101744413375854, 'step': 529},\n",
       "  {'loss': 0.4972039461135864, 'step': 530},\n",
       "  {'loss': 0.5827326774597168, 'step': 531},\n",
       "  {'loss': 0.4053134322166443, 'step': 532},\n",
       "  {'loss': 0.18882963061332703, 'step': 533},\n",
       "  {'loss': 0.43211841583251953, 'step': 534},\n",
       "  {'loss': 0.47656047344207764, 'step': 535},\n",
       "  {'loss': 0.4723433554172516, 'step': 536},\n",
       "  {'loss': 0.6280435919761658, 'step': 537},\n",
       "  {'loss': 0.8762224912643433, 'step': 538},\n",
       "  {'loss': 0.5812748670578003, 'step': 539},\n",
       "  {'loss': 0.7849679589271545, 'step': 540},\n",
       "  {'loss': 0.280973345041275, 'step': 541},\n",
       "  {'loss': 0.536937415599823, 'step': 542},\n",
       "  {'loss': 0.4044930040836334, 'step': 543},\n",
       "  {'loss': 1.9053363800048828, 'step': 544},\n",
       "  {'loss': 0.4651169776916504, 'step': 545},\n",
       "  {'loss': 0.1822911500930786, 'step': 546},\n",
       "  {'loss': 0.3124053180217743, 'step': 547},\n",
       "  {'loss': 0.2854258120059967, 'step': 548},\n",
       "  {'loss': 0.3407251238822937, 'step': 549},\n",
       "  {'loss': 0.35455673933029175, 'step': 550},\n",
       "  {'loss': 0.5012112855911255, 'step': 551},\n",
       "  {'loss': 0.19920888543128967, 'step': 552},\n",
       "  {'loss': 0.20136314630508423, 'step': 553},\n",
       "  {'loss': 0.19744203984737396, 'step': 554},\n",
       "  {'loss': 0.4612032473087311, 'step': 555},\n",
       "  {'loss': 0.2577001452445984, 'step': 556},\n",
       "  {'loss': 1.0707275867462158, 'step': 557},\n",
       "  {'loss': 0.8053125739097595, 'step': 558},\n",
       "  {'loss': 0.2989703416824341, 'step': 559},\n",
       "  {'loss': 0.3373706042766571, 'step': 560},\n",
       "  {'loss': 0.2155812829732895, 'step': 561},\n",
       "  {'loss': 0.15419480204582214, 'step': 562},\n",
       "  {'loss': 0.49084872007369995, 'step': 563},\n",
       "  {'loss': 0.31366702914237976, 'step': 564},\n",
       "  {'loss': 0.10930542647838593, 'step': 565},\n",
       "  {'loss': 0.34726619720458984, 'step': 566},\n",
       "  {'loss': 0.2241545468568802, 'step': 567},\n",
       "  {'loss': 1.0990779399871826, 'step': 568},\n",
       "  {'loss': 0.2196645438671112, 'step': 569},\n",
       "  {'loss': 0.3712795674800873, 'step': 570},\n",
       "  {'loss': 0.22115474939346313, 'step': 571},\n",
       "  {'loss': 0.45968756079673767, 'step': 572},\n",
       "  {'loss': 0.11808909475803375, 'step': 573},\n",
       "  {'loss': 0.6030341982841492, 'step': 574},\n",
       "  {'loss': 0.4859733581542969, 'step': 575},\n",
       "  {'loss': 0.35852712392807007, 'step': 576},\n",
       "  {'loss': 0.1844949573278427, 'step': 577},\n",
       "  {'loss': 0.8940756916999817, 'step': 578},\n",
       "  {'loss': 0.8016732931137085, 'step': 579},\n",
       "  {'loss': 0.7633368968963623, 'step': 580},\n",
       "  {'loss': 0.36680522561073303, 'step': 581},\n",
       "  {'loss': 0.2962956428527832, 'step': 582},\n",
       "  {'loss': 0.2320854663848877, 'step': 583},\n",
       "  {'loss': 0.2944674491882324, 'step': 584},\n",
       "  {'loss': 0.37229251861572266, 'step': 585},\n",
       "  {'loss': 0.6401208639144897, 'step': 586},\n",
       "  {'loss': 0.9460175633430481, 'step': 587},\n",
       "  {'loss': 0.5400933027267456, 'step': 588},\n",
       "  {'loss': 0.7224919199943542, 'step': 589},\n",
       "  {'loss': 1.5514953136444092, 'step': 590},\n",
       "  {'loss': 0.2378569096326828, 'step': 591},\n",
       "  {'loss': 0.2303485870361328, 'step': 592},\n",
       "  {'loss': 0.37599828839302063, 'step': 593},\n",
       "  {'loss': 0.302274614572525, 'step': 594},\n",
       "  {'loss': 0.3812248110771179, 'step': 595},\n",
       "  {'loss': 0.3871033787727356, 'step': 596},\n",
       "  {'loss': 0.9353423118591309, 'step': 597},\n",
       "  {'loss': 0.948204755783081, 'step': 598},\n",
       "  {'loss': 0.6162911653518677, 'step': 599},\n",
       "  {'loss': 0.538783609867096, 'step': 600},\n",
       "  {'loss': 0.2682187557220459, 'step': 601},\n",
       "  {'loss': 0.2933233380317688, 'step': 602},\n",
       "  {'loss': 0.7585535645484924, 'step': 603},\n",
       "  {'loss': 0.21874842047691345, 'step': 604},\n",
       "  {'loss': 0.37780237197875977, 'step': 605},\n",
       "  {'loss': 0.39910009503364563, 'step': 606},\n",
       "  {'loss': 0.1115516722202301, 'step': 607},\n",
       "  {'loss': 0.4656415581703186, 'step': 608},\n",
       "  {'loss': 0.19819845259189606, 'step': 609},\n",
       "  {'loss': 0.23110425472259521, 'step': 610},\n",
       "  {'loss': 0.19282901287078857, 'step': 611},\n",
       "  {'loss': 1.159925103187561, 'step': 612},\n",
       "  {'loss': 0.6978536248207092, 'step': 613},\n",
       "  {'loss': 0.27407050132751465, 'step': 614},\n",
       "  {'loss': 0.4819648861885071, 'step': 615},\n",
       "  {'loss': 0.4836607575416565, 'step': 616},\n",
       "  {'loss': 0.5703223347663879, 'step': 617},\n",
       "  {'loss': 0.277188777923584, 'step': 618},\n",
       "  {'loss': 0.309646874666214, 'step': 619},\n",
       "  {'loss': 0.3814243972301483, 'step': 620},\n",
       "  {'loss': 0.37128549814224243, 'step': 621},\n",
       "  {'loss': 0.2658829391002655, 'step': 622},\n",
       "  {'loss': 0.3407113254070282, 'step': 623},\n",
       "  {'loss': 0.36585739254951477, 'step': 624},\n",
       "  {'loss': 0.6286337375640869, 'step': 625},\n",
       "  {'loss': 0.3975462317466736, 'step': 626},\n",
       "  {'loss': 0.4297271966934204, 'step': 627},\n",
       "  {'loss': 0.3406784236431122, 'step': 628},\n",
       "  {'loss': 1.1678714752197266, 'step': 629},\n",
       "  {'loss': 0.5526379942893982, 'step': 630},\n",
       "  {'loss': 0.8178164958953857, 'step': 631},\n",
       "  {'loss': 0.42053675651550293, 'step': 632},\n",
       "  {'loss': 0.21190138161182404, 'step': 633},\n",
       "  {'loss': 0.7052921056747437, 'step': 634},\n",
       "  {'loss': 1.1962988376617432, 'step': 635},\n",
       "  {'loss': 0.9144012928009033, 'step': 636},\n",
       "  {'loss': 0.40061190724372864, 'step': 637},\n",
       "  {'loss': 0.5000026822090149, 'step': 638},\n",
       "  {'loss': 0.8327081203460693, 'step': 639},\n",
       "  {'loss': 0.3799579441547394, 'step': 640},\n",
       "  {'loss': 1.0239050388336182, 'step': 641},\n",
       "  {'loss': 0.7479926347732544, 'step': 642},\n",
       "  {'loss': 0.18817715346813202, 'step': 643},\n",
       "  {'loss': 0.7679175138473511, 'step': 644},\n",
       "  {'loss': 0.8776155710220337, 'step': 645},\n",
       "  {'loss': 0.19586914777755737, 'step': 646},\n",
       "  {'loss': 0.2564873695373535, 'step': 647},\n",
       "  {'loss': 0.2396400421857834, 'step': 648},\n",
       "  {'loss': 0.2075861543416977, 'step': 649},\n",
       "  {'loss': 0.4539298415184021, 'step': 650},\n",
       "  {'loss': 0.17296656966209412, 'step': 651},\n",
       "  {'loss': 0.4677952229976654, 'step': 652},\n",
       "  {'loss': 0.31382542848587036, 'step': 653},\n",
       "  {'loss': 0.24215736985206604, 'step': 654},\n",
       "  {'loss': 0.3614555597305298, 'step': 655},\n",
       "  {'loss': 0.28698015213012695, 'step': 656},\n",
       "  {'loss': 0.8227975368499756, 'step': 657},\n",
       "  {'loss': 1.2950507402420044, 'step': 658},\n",
       "  {'loss': 0.4769030809402466, 'step': 659},\n",
       "  {'loss': 0.518392026424408, 'step': 660},\n",
       "  {'loss': 0.3819091320037842, 'step': 661},\n",
       "  {'loss': 0.3497803509235382, 'step': 662},\n",
       "  {'loss': 0.49172019958496094, 'step': 663},\n",
       "  {'loss': 0.37604638934135437, 'step': 664},\n",
       "  {'loss': 0.2785499393939972, 'step': 665},\n",
       "  {'loss': 0.7427309155464172, 'step': 666},\n",
       "  {'loss': 0.42730799317359924, 'step': 667},\n",
       "  {'loss': 0.854581356048584, 'step': 668},\n",
       "  {'loss': 0.5582051873207092, 'step': 669},\n",
       "  {'loss': 0.17916709184646606, 'step': 670},\n",
       "  {'loss': 1.000015139579773, 'step': 671},\n",
       "  {'loss': 0.7098942399024963, 'step': 672},\n",
       "  {'loss': 0.3604886829853058, 'step': 673},\n",
       "  {'loss': 1.0869760513305664, 'step': 674},\n",
       "  {'loss': 0.5064849853515625, 'step': 675},\n",
       "  {'loss': 0.2297002077102661, 'step': 676},\n",
       "  {'loss': 0.4760620594024658, 'step': 677},\n",
       "  {'loss': 0.8547961711883545, 'step': 678},\n",
       "  {'loss': 2.334798812866211, 'step': 679},\n",
       "  {'loss': 0.23076286911964417, 'step': 680},\n",
       "  {'loss': 0.29421913623809814, 'step': 681},\n",
       "  {'loss': 0.3618505597114563, 'step': 682},\n",
       "  {'loss': 0.3147883415222168, 'step': 683},\n",
       "  {'loss': 0.5001116394996643, 'step': 684},\n",
       "  {'loss': 0.1896500289440155, 'step': 685},\n",
       "  {'loss': 0.44530197978019714, 'step': 686},\n",
       "  {'loss': 0.3178342878818512, 'step': 687},\n",
       "  {'loss': 0.8050366640090942, 'step': 688},\n",
       "  {'loss': 0.45953071117401123, 'step': 689},\n",
       "  {'loss': 0.43481671810150146, 'step': 690},\n",
       "  {'loss': 0.30007046461105347, 'step': 691},\n",
       "  {'loss': 0.4166097342967987, 'step': 692},\n",
       "  {'loss': 0.30897679924964905, 'step': 693},\n",
       "  {'loss': 0.29418301582336426, 'step': 694},\n",
       "  {'loss': 0.2976246476173401, 'step': 695},\n",
       "  {'loss': 0.3186438977718353, 'step': 696},\n",
       "  {'loss': 1.035057544708252, 'step': 697},\n",
       "  {'loss': 0.5453953146934509, 'step': 698},\n",
       "  {'loss': 0.41230273246765137, 'step': 699},\n",
       "  {'loss': 0.39826667308807373, 'step': 700},\n",
       "  {'loss': 0.10637183487415314, 'step': 701},\n",
       "  {'loss': 0.3180561363697052, 'step': 702},\n",
       "  {'loss': 0.2631961703300476, 'step': 703},\n",
       "  {'loss': 0.1851280927658081, 'step': 704},\n",
       "  {'loss': 1.3004810810089111, 'step': 705},\n",
       "  {'loss': 0.31469449400901794, 'step': 706},\n",
       "  {'loss': 0.2157079130411148, 'step': 707},\n",
       "  {'loss': 0.2767634093761444, 'step': 708},\n",
       "  {'loss': 0.2168101966381073, 'step': 709},\n",
       "  {'loss': 0.26675835251808167, 'step': 710},\n",
       "  {'loss': 0.21945279836654663, 'step': 711},\n",
       "  {'loss': 0.6100741028785706, 'step': 712},\n",
       "  {'loss': 0.15942806005477905, 'step': 713},\n",
       "  {'loss': 0.995845377445221, 'step': 714},\n",
       "  {'loss': 0.4439970552921295, 'step': 715},\n",
       "  {'loss': 0.534846305847168, 'step': 716},\n",
       "  {'loss': 0.32180044054985046, 'step': 717},\n",
       "  {'loss': 0.21098817884922028, 'step': 718},\n",
       "  {'loss': 1.3188751935958862, 'step': 719},\n",
       "  {'loss': 0.23527619242668152, 'step': 720},\n",
       "  {'loss': 0.3075481951236725, 'step': 721},\n",
       "  {'loss': 0.17523810267448425, 'step': 722},\n",
       "  {'loss': 0.602171003818512, 'step': 723},\n",
       "  {'loss': 0.41044577956199646, 'step': 724},\n",
       "  {'loss': 0.3788275420665741, 'step': 725},\n",
       "  {'loss': 0.22358328104019165, 'step': 726},\n",
       "  {'loss': 0.5981006622314453, 'step': 727},\n",
       "  {'loss': 0.425973117351532, 'step': 728},\n",
       "  {'loss': 0.2833854556083679, 'step': 729},\n",
       "  {'loss': 0.23239760100841522, 'step': 730},\n",
       "  {'loss': 0.35820281505584717, 'step': 731},\n",
       "  {'loss': 0.6808887124061584, 'step': 732},\n",
       "  {'loss': 0.3228427767753601, 'step': 733},\n",
       "  {'loss': 1.086612582206726, 'step': 734},\n",
       "  {'loss': 0.5710375905036926, 'step': 735},\n",
       "  {'loss': 0.2949541509151459, 'step': 736},\n",
       "  {'loss': 0.2861950993537903, 'step': 737},\n",
       "  {'loss': 0.801230788230896, 'step': 738},\n",
       "  {'loss': 0.5241491198539734, 'step': 739},\n",
       "  {'loss': 0.3542476296424866, 'step': 740},\n",
       "  {'loss': 0.23229257762432098, 'step': 741},\n",
       "  {'loss': 1.4240198135375977, 'step': 742},\n",
       "  {'loss': 0.08447666466236115, 'step': 743},\n",
       "  {'loss': 0.38437169790267944, 'step': 744},\n",
       "  {'loss': 1.2409346103668213, 'step': 745},\n",
       "  {'loss': 0.6296464800834656, 'step': 746},\n",
       "  {'loss': 0.5232877135276794, 'step': 747},\n",
       "  {'loss': 0.25770655274391174, 'step': 748},\n",
       "  {'loss': 0.3242036998271942, 'step': 749},\n",
       "  {'loss': 0.7890937328338623, 'step': 750},\n",
       "  {'loss': 0.8370213508605957, 'step': 751},\n",
       "  {'loss': 0.8724890351295471, 'step': 752},\n",
       "  {'loss': 0.25772058963775635, 'step': 753},\n",
       "  {'loss': 0.9930541515350342, 'step': 754},\n",
       "  {'loss': 0.9478169083595276, 'step': 755},\n",
       "  {'loss': 0.38779884576797485, 'step': 756},\n",
       "  {'loss': 0.5850799083709717, 'step': 757},\n",
       "  {'loss': 1.0085506439208984, 'step': 758},\n",
       "  {'loss': 0.12398212403059006, 'step': 759},\n",
       "  {'loss': 0.32101675868034363, 'step': 760},\n",
       "  {'loss': 0.31324630975723267, 'step': 761},\n",
       "  {'loss': 0.2571989893913269, 'step': 762},\n",
       "  {'loss': 0.35534945130348206, 'step': 763},\n",
       "  {'loss': 0.39261043071746826, 'step': 764},\n",
       "  {'loss': 0.19008255004882812, 'step': 765},\n",
       "  {'loss': 0.8277475237846375, 'step': 766},\n",
       "  {'loss': 0.5237599015235901, 'step': 767},\n",
       "  {'loss': 0.22087593376636505, 'step': 768},\n",
       "  {'loss': 0.48722147941589355, 'step': 769},\n",
       "  {'loss': 0.5150215029716492, 'step': 770},\n",
       "  {'loss': 0.2252313494682312, 'step': 771},\n",
       "  {'loss': 0.49235108494758606, 'step': 772},\n",
       "  {'loss': 0.29601365327835083, 'step': 773},\n",
       "  {'loss': 0.5784881711006165, 'step': 774},\n",
       "  {'loss': 0.327693372964859, 'step': 775},\n",
       "  {'loss': 0.4023491144180298, 'step': 776},\n",
       "  {'loss': 0.6321039199829102, 'step': 777},\n",
       "  {'loss': 0.335732102394104, 'step': 778},\n",
       "  {'loss': 0.4214943051338196, 'step': 779},\n",
       "  {'loss': 0.6546810865402222, 'step': 780},\n",
       "  {'loss': 0.7609255313873291, 'step': 781},\n",
       "  {'loss': 0.8573395609855652, 'step': 782},\n",
       "  {'loss': 0.8057754039764404, 'step': 783},\n",
       "  {'loss': 0.7289889454841614, 'step': 784},\n",
       "  {'loss': 0.19284282624721527, 'step': 785},\n",
       "  {'loss': 0.3311837315559387, 'step': 786},\n",
       "  {'loss': 0.33438655734062195, 'step': 787},\n",
       "  {'loss': 0.3946380317211151, 'step': 788},\n",
       "  {'loss': 0.4069086015224457, 'step': 789},\n",
       "  {'loss': 0.8050611019134521, 'step': 790},\n",
       "  {'loss': 0.11898194998502731, 'step': 791},\n",
       "  {'loss': 1.1215782165527344, 'step': 792},\n",
       "  {'loss': 0.26732176542282104, 'step': 793},\n",
       "  {'loss': 0.31457555294036865, 'step': 794},\n",
       "  {'loss': 0.4037495255470276, 'step': 795},\n",
       "  {'loss': 0.6275091171264648, 'step': 796},\n",
       "  {'loss': 0.26685404777526855, 'step': 797},\n",
       "  {'loss': 0.14241190254688263, 'step': 798},\n",
       "  {'loss': 0.5125451683998108, 'step': 799},\n",
       "  {'loss': 0.3996237814426422, 'step': 800},\n",
       "  {'loss': 0.2443818598985672, 'step': 801},\n",
       "  {'loss': 0.529516339302063, 'step': 802},\n",
       "  {'loss': 0.2167295217514038, 'step': 803},\n",
       "  {'loss': 0.3251808285713196, 'step': 804},\n",
       "  {'loss': 0.326866090297699, 'step': 805},\n",
       "  {'loss': 0.1495482623577118, 'step': 806},\n",
       "  {'loss': 0.39336147904396057, 'step': 807},\n",
       "  {'loss': 0.6358123421669006, 'step': 808},\n",
       "  {'loss': 0.2604767084121704, 'step': 809},\n",
       "  {'loss': 0.32439765334129333, 'step': 810},\n",
       "  {'loss': 0.8908404111862183, 'step': 811},\n",
       "  {'loss': 0.4807116389274597, 'step': 812},\n",
       "  {'loss': 0.21213167905807495, 'step': 813},\n",
       "  {'loss': 0.28357940912246704, 'step': 814},\n",
       "  {'loss': 0.4326746165752411, 'step': 815},\n",
       "  {'loss': 0.9559309482574463, 'step': 816},\n",
       "  {'loss': 0.2787240445613861, 'step': 817},\n",
       "  {'loss': 0.6316395401954651, 'step': 818},\n",
       "  {'loss': 0.1758170872926712, 'step': 819},\n",
       "  {'loss': 1.3277682065963745, 'step': 820},\n",
       "  {'loss': 0.6783962249755859, 'step': 821},\n",
       "  {'loss': 0.3135434091091156, 'step': 822},\n",
       "  {'loss': 0.4108981490135193, 'step': 823},\n",
       "  {'loss': 0.1902225911617279, 'step': 824},\n",
       "  {'loss': 0.7423884868621826, 'step': 825},\n",
       "  {'loss': 0.21689508855342865, 'step': 826},\n",
       "  {'loss': 0.6793562769889832, 'step': 827},\n",
       "  {'loss': 0.24241839349269867, 'step': 828},\n",
       "  {'loss': 0.8434467911720276, 'step': 829},\n",
       "  {'loss': 0.13342489302158356, 'step': 830},\n",
       "  {'loss': 0.8024632334709167, 'step': 831},\n",
       "  {'loss': 0.2238152027130127, 'step': 832},\n",
       "  {'loss': 0.20840735733509064, 'step': 833},\n",
       "  {'loss': 0.5310297012329102, 'step': 834},\n",
       "  {'loss': 0.7755639553070068, 'step': 835},\n",
       "  {'loss': 0.1354556679725647, 'step': 836},\n",
       "  {'loss': 0.8816814422607422, 'step': 837},\n",
       "  {'loss': 0.1667298972606659, 'step': 838},\n",
       "  {'loss': 0.49398475885391235, 'step': 839},\n",
       "  {'loss': 0.15552854537963867, 'step': 840},\n",
       "  {'loss': 0.2991684675216675, 'step': 841},\n",
       "  {'loss': 0.22458234429359436, 'step': 842},\n",
       "  {'loss': 0.7003955245018005, 'step': 843},\n",
       "  {'loss': 0.38027724623680115, 'step': 844},\n",
       "  {'loss': 0.4646620750427246, 'step': 845},\n",
       "  {'loss': 0.30190911889076233, 'step': 846},\n",
       "  {'loss': 0.3126869797706604, 'step': 847},\n",
       "  {'loss': 0.9375942349433899, 'step': 848},\n",
       "  {'loss': 0.5861087441444397, 'step': 849},\n",
       "  {'loss': 0.5235298275947571, 'step': 850},\n",
       "  {'loss': 0.284366250038147, 'step': 851},\n",
       "  {'loss': 0.3783957362174988, 'step': 852},\n",
       "  {'loss': 0.39840811491012573, 'step': 853},\n",
       "  {'loss': 0.4469950199127197, 'step': 854},\n",
       "  {'loss': 0.7434581518173218, 'step': 855},\n",
       "  {'loss': 0.5351186990737915, 'step': 856},\n",
       "  {'loss': 0.8883365392684937, 'step': 857},\n",
       "  {'loss': 0.28340715169906616, 'step': 858},\n",
       "  {'loss': 0.45806053280830383, 'step': 859},\n",
       "  {'loss': 0.2501305043697357, 'step': 860},\n",
       "  {'loss': 0.29661697149276733, 'step': 861},\n",
       "  {'loss': 0.34896621108055115, 'step': 862},\n",
       "  {'loss': 0.45977482199668884, 'step': 863},\n",
       "  {'loss': 0.45913130044937134, 'step': 864},\n",
       "  {'loss': 0.47483953833580017, 'step': 865},\n",
       "  {'loss': 0.7613413333892822, 'step': 866},\n",
       "  {'loss': 0.993637204170227, 'step': 867},\n",
       "  {'loss': 0.20380398631095886, 'step': 868},\n",
       "  {'loss': 0.6223621368408203, 'step': 869},\n",
       "  {'loss': 0.46988728642463684, 'step': 870},\n",
       "  {'loss': 0.34993764758110046, 'step': 871},\n",
       "  {'loss': 0.7690231800079346, 'step': 872},\n",
       "  {'loss': 0.28491002321243286, 'step': 873},\n",
       "  {'loss': 0.6445353031158447, 'step': 874},\n",
       "  {'loss': 0.2910623550415039, 'step': 875},\n",
       "  {'loss': 0.4544072449207306, 'step': 876},\n",
       "  {'loss': 0.41814255714416504, 'step': 877},\n",
       "  {'loss': 0.31221985816955566, 'step': 878},\n",
       "  {'loss': 0.2861059606075287, 'step': 879},\n",
       "  {'loss': 0.2772914171218872, 'step': 880},\n",
       "  {'loss': 0.23089034855365753, 'step': 881},\n",
       "  {'loss': 0.26090043783187866, 'step': 882},\n",
       "  {'loss': 0.280290812253952, 'step': 883},\n",
       "  {'loss': 0.16073602437973022, 'step': 884},\n",
       "  {'loss': 0.4004088044166565, 'step': 885},\n",
       "  {'loss': 0.5875168442726135, 'step': 886},\n",
       "  {'loss': 0.353948175907135, 'step': 887},\n",
       "  {'loss': 0.20536546409130096, 'step': 888},\n",
       "  {'loss': 0.17934206128120422, 'step': 889},\n",
       "  {'loss': 0.2619137465953827, 'step': 890},\n",
       "  {'loss': 0.3762724697589874, 'step': 891},\n",
       "  {'loss': 0.2695615291595459, 'step': 892},\n",
       "  {'loss': 0.5251030921936035, 'step': 893},\n",
       "  {'loss': 0.8026162385940552, 'step': 894},\n",
       "  {'loss': 0.9733285307884216, 'step': 895},\n",
       "  {'loss': 0.2339823693037033, 'step': 896},\n",
       "  {'loss': 0.5666525363922119, 'step': 897},\n",
       "  {'loss': 0.25141510367393494, 'step': 898},\n",
       "  {'loss': 0.13760939240455627, 'step': 899},\n",
       "  {'loss': 0.3202298879623413, 'step': 900},\n",
       "  {'loss': 0.6981997489929199, 'step': 901},\n",
       "  {'loss': 0.4226962924003601, 'step': 902},\n",
       "  {'loss': 0.3552170991897583, 'step': 903},\n",
       "  {'loss': 0.30564409494400024, 'step': 904},\n",
       "  {'loss': 0.429882675409317, 'step': 905},\n",
       "  {'loss': 0.14259950816631317, 'step': 906},\n",
       "  {'loss': 0.2966423034667969, 'step': 907},\n",
       "  {'loss': 0.25999370217323303, 'step': 908},\n",
       "  {'loss': 0.3546978831291199, 'step': 909},\n",
       "  {'loss': 0.3046022951602936, 'step': 910},\n",
       "  {'loss': 0.316855251789093, 'step': 911},\n",
       "  {'loss': 0.1941322386264801, 'step': 912},\n",
       "  {'loss': 0.3818773627281189, 'step': 913},\n",
       "  {'loss': 0.4098191261291504, 'step': 914},\n",
       "  {'loss': 0.23530100286006927, 'step': 915},\n",
       "  {'loss': 0.7055963277816772, 'step': 916},\n",
       "  {'loss': 0.15900325775146484, 'step': 917},\n",
       "  {'loss': 0.1474110633134842, 'step': 918},\n",
       "  {'loss': 0.22991737723350525, 'step': 919},\n",
       "  {'loss': 0.5615242719650269, 'step': 920},\n",
       "  {'loss': 0.35827499628067017, 'step': 921},\n",
       "  {'loss': 0.2576243281364441, 'step': 922},\n",
       "  {'loss': 0.40932559967041016, 'step': 923},\n",
       "  {'loss': 0.41142261028289795, 'step': 924},\n",
       "  {'loss': 0.5462583303451538, 'step': 925},\n",
       "  {'loss': 0.7218597531318665, 'step': 926},\n",
       "  {'loss': 0.11282780766487122, 'step': 927},\n",
       "  {'loss': 0.23724518716335297, 'step': 928},\n",
       "  {'loss': 0.23845626413822174, 'step': 929},\n",
       "  {'loss': 0.6516249179840088, 'step': 930},\n",
       "  {'loss': 0.147587850689888, 'step': 931},\n",
       "  {'loss': 0.7223859429359436, 'step': 932},\n",
       "  {'loss': 0.06265397369861603, 'step': 933},\n",
       "  {'loss': 0.1703043282032013, 'step': 934},\n",
       "  {'loss': 0.1929095983505249, 'step': 935},\n",
       "  {'loss': 0.9612637758255005, 'step': 936},\n",
       "  {'loss': 0.6291773915290833, 'step': 937},\n",
       "  {'loss': 0.44208478927612305, 'step': 938},\n",
       "  {'loss': 0.4275902807712555, 'step': 939},\n",
       "  {'loss': 0.33602187037467957, 'step': 940},\n",
       "  {'loss': 0.6093594431877136, 'step': 941},\n",
       "  {'loss': 0.16905370354652405, 'step': 942},\n",
       "  {'loss': 0.27749425172805786, 'step': 943},\n",
       "  {'loss': 0.7812161445617676, 'step': 944},\n",
       "  {'loss': 0.8719254732131958, 'step': 945},\n",
       "  {'loss': 0.48033004999160767, 'step': 946},\n",
       "  {'loss': 0.5315691828727722, 'step': 947},\n",
       "  {'loss': 0.7070913314819336, 'step': 948},\n",
       "  {'loss': 0.5124754905700684, 'step': 949},\n",
       "  {'loss': 0.26088976860046387, 'step': 950},\n",
       "  {'loss': 0.3713037967681885, 'step': 951},\n",
       "  {'loss': 1.0251706838607788, 'step': 952},\n",
       "  {'loss': 0.27069830894470215, 'step': 953},\n",
       "  {'loss': 0.41225767135620117, 'step': 954},\n",
       "  {'loss': 0.8331321477890015, 'step': 955},\n",
       "  {'loss': 0.20583249628543854, 'step': 956},\n",
       "  {'loss': 0.4785747528076172, 'step': 957},\n",
       "  {'loss': 0.434276282787323, 'step': 958},\n",
       "  {'loss': 0.6148836612701416, 'step': 959},\n",
       "  {'loss': 0.33797749876976013, 'step': 960},\n",
       "  {'loss': 0.6301157474517822, 'step': 961},\n",
       "  {'loss': 0.9360690116882324, 'step': 962},\n",
       "  {'loss': 0.34536561369895935, 'step': 963},\n",
       "  {'loss': 0.42261847853660583, 'step': 964},\n",
       "  {'loss': 0.6098690629005432, 'step': 965},\n",
       "  {'loss': 0.2214718461036682, 'step': 966},\n",
       "  {'loss': 0.5056482553482056, 'step': 967},\n",
       "  {'loss': 0.5070872902870178, 'step': 968},\n",
       "  {'loss': 0.45643433928489685, 'step': 969},\n",
       "  {'loss': 0.3664075434207916, 'step': 970},\n",
       "  {'loss': 0.2521282732486725, 'step': 971},\n",
       "  {'loss': 0.1890040934085846, 'step': 972},\n",
       "  {'loss': 0.6119109392166138, 'step': 973},\n",
       "  {'loss': 0.7787364721298218, 'step': 974},\n",
       "  {'loss': 0.29464903473854065, 'step': 975},\n",
       "  {'loss': 0.4635099172592163, 'step': 976},\n",
       "  {'loss': 0.4622204005718231, 'step': 977},\n",
       "  {'loss': 0.5454226732254028, 'step': 978},\n",
       "  {'loss': 0.23074977099895477, 'step': 979},\n",
       "  {'loss': 0.44960570335388184, 'step': 980},\n",
       "  {'loss': 0.20487909018993378, 'step': 981},\n",
       "  {'loss': 0.47415149211883545, 'step': 982},\n",
       "  {'loss': 0.22117513418197632, 'step': 983},\n",
       "  {'loss': 1.0545167922973633, 'step': 984},\n",
       "  {'loss': 0.21930134296417236, 'step': 985},\n",
       "  {'loss': 0.6494985222816467, 'step': 986},\n",
       "  {'loss': 0.2385486215353012, 'step': 987},\n",
       "  {'loss': 0.3867896795272827, 'step': 988},\n",
       "  {'loss': 0.7450897693634033, 'step': 989},\n",
       "  {'loss': 0.2915710508823395, 'step': 990},\n",
       "  {'loss': 0.6059643030166626, 'step': 991},\n",
       "  {'loss': 0.1870238035917282, 'step': 992},\n",
       "  {'loss': 0.8109937310218811, 'step': 993},\n",
       "  {'loss': 0.32406139373779297, 'step': 994},\n",
       "  {'loss': 0.44996851682662964, 'step': 995},\n",
       "  {'loss': 0.59343421459198, 'step': 996},\n",
       "  {'loss': 0.13319797813892365, 'step': 997},\n",
       "  {'loss': 0.299398273229599, 'step': 998},\n",
       "  {'loss': 0.35345035791397095, 'step': 999},\n",
       "  ...],\n",
       " 'val': [{'loss': 6.03419651374344, 'step': 0},\n",
       "  {'loss': 0.4713980257511139, 'step': 726},\n",
       "  {'loss': 0.4382366973075492, 'step': 1452},\n",
       "  {'loss': 0.41912029932968875, 'step': 2178},\n",
       "  {'loss': 0.4138904985440664, 'step': 2904},\n",
       "  {'loss': 0.4018156056192296, 'step': 3630},\n",
       "  {'loss': 0.3916843684682669, 'step': 4356},\n",
       "  {'loss': 0.39545653529526775, 'step': 5082},\n",
       "  {'loss': 0.4022085542582776, 'step': 5808},\n",
       "  {'loss': 0.3915211060507731, 'step': 6534},\n",
       "  {'loss': 0.37992488398901686, 'step': 7260},\n",
       "  {'loss': 0.37526190345568106, 'step': 7986},\n",
       "  {'loss': 0.3777438254703668, 'step': 8712},\n",
       "  {'loss': 0.37299440724174837, 'step': 9438},\n",
       "  {'loss': 0.6168132873544515, 'step': 10164},\n",
       "  {'loss': 0.3723774076985919, 'step': 10890},\n",
       "  {'loss': 0.3627783843308441, 'step': 11616},\n",
       "  {'loss': 0.3993540218731096, 'step': 12342},\n",
       "  {'loss': 0.3607214466968844, 'step': 13068},\n",
       "  {'loss': 0.36130854545915425, 'step': 13794},\n",
       "  {'loss': 0.3639861320045369, 'step': 14520},\n",
       "  {'loss': 0.36238531078681474, 'step': 15246},\n",
       "  {'loss': 0.3566558243445128, 'step': 15972},\n",
       "  {'loss': 0.358942946927114, 'step': 16698},\n",
       "  {'loss': 0.35753977689738115, 'step': 17424},\n",
       "  {'loss': 0.3589164133776318, 'step': 18150},\n",
       "  {'loss': 0.3548151325003421, 'step': 18876},\n",
       "  {'loss': 0.35433264058237235, 'step': 19602},\n",
       "  {'loss': 0.3601209177704882, 'step': 20328},\n",
       "  {'loss': 0.36080962736621375, 'step': 21054},\n",
       "  {'loss': 0.37568465894288267, 'step': 21780},\n",
       "  {'loss': 0.3572954924638606, 'step': 22506},\n",
       "  {'loss': 0.3509703397073529, 'step': 23232},\n",
       "  {'loss': 0.35319596285785526, 'step': 23958},\n",
       "  {'loss': 0.3448531632581033, 'step': 24684},\n",
       "  {'loss': 0.34986764598976483, 'step': 25410},\n",
       "  {'loss': 0.34471970852002626, 'step': 26136},\n",
       "  {'loss': 0.3422987931523441, 'step': 26862},\n",
       "  {'loss': 0.34608794958138267, 'step': 27588},\n",
       "  {'loss': 0.3384712768549269, 'step': 28314},\n",
       "  {'loss': 0.3463737401064516, 'step': 29040},\n",
       "  {'loss': 0.33843654395689154, 'step': 29766},\n",
       "  {'loss': 0.3375858070621313, 'step': 30492},\n",
       "  {'loss': 0.3388392683272519, 'step': 31218},\n",
       "  {'loss': 0.34366871601293897, 'step': 31944},\n",
       "  {'loss': 0.33528832258456504, 'step': 32670},\n",
       "  {'loss': 0.3607053492095106, 'step': 33396},\n",
       "  {'loss': 0.33340988682259703, 'step': 34122},\n",
       "  {'loss': 0.3327809622711387, 'step': 34848},\n",
       "  {'loss': 0.34121202877607226, 'step': 35574},\n",
       "  {'loss': 0.3408510102928916, 'step': 36300},\n",
       "  {'loss': 0.34736299311572855, 'step': 37026},\n",
       "  {'loss': 0.3327066865557235, 'step': 37752},\n",
       "  {'loss': 0.3430732384570374, 'step': 38478},\n",
       "  {'loss': 0.3357027417187356, 'step': 39204},\n",
       "  {'loss': 0.33640636201978713, 'step': 39930},\n",
       "  {'loss': 0.3298382486316783, 'step': 40656},\n",
       "  {'loss': 0.33200195333189214, 'step': 41382},\n",
       "  {'loss': 0.3355274565887353, 'step': 42108},\n",
       "  {'loss': 0.3296499723830253, 'step': 42834},\n",
       "  {'loss': 0.3270485682089713, 'step': 43560},\n",
       "  {'loss': 0.33018006687629814, 'step': 44286},\n",
       "  {'loss': 0.34271333465152537, 'step': 45012},\n",
       "  {'loss': 0.3335600354793397, 'step': 45738},\n",
       "  {'loss': 0.32646169584275275, 'step': 46464},\n",
       "  {'loss': 0.3281849433075298, 'step': 47190},\n",
       "  {'loss': 0.3335106044792193, 'step': 47916},\n",
       "  {'loss': 0.32762741362137243, 'step': 48642},\n",
       "  {'loss': 0.33448033946112166, 'step': 49368},\n",
       "  {'loss': 0.3258334524190623, 'step': 50094},\n",
       "  {'loss': 0.3315305383798997, 'step': 50820},\n",
       "  {'loss': 0.3213541719693044, 'step': 51546},\n",
       "  {'loss': 0.34802670036404093, 'step': 52272},\n",
       "  {'loss': 0.326816362351918, 'step': 52998},\n",
       "  {'loss': 0.3202073752633796, 'step': 53724},\n",
       "  {'loss': 0.32388097757458195, 'step': 54450},\n",
       "  {'loss': 0.3278856972955968, 'step': 55176},\n",
       "  {'loss': 0.3331231169156299, 'step': 55902},\n",
       "  {'loss': 0.3270988552407785, 'step': 56628},\n",
       "  {'loss': 0.32491796885517016, 'step': 57354},\n",
       "  {'loss': 0.32715592299364815, 'step': 58080},\n",
       "  {'loss': 0.328431987180567, 'step': 58806},\n",
       "  {'loss': 0.33781086080823064, 'step': 59532},\n",
       "  {'loss': 0.3267918818684156, 'step': 60258},\n",
       "  {'loss': 0.3289724752799539, 'step': 60984}]}"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 34
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T14:29:34.706625Z",
     "start_time": "2025-01-16T14:29:34.535808Z"
    }
   },
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # plot\n",
    "    for idx, item in enumerate(train_df.columns):\n",
    "        plt.plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        plt.plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        plt.grid()\n",
    "        plt.legend()\n",
    "        # plt.xticks(range(0, train_df.index[-1], 10*sample_step), range(0, train_df.index[-1], 10*sample_step))\n",
    "        plt.xlabel(\"step\")\n",
    "\n",
    "        plt.show()\n",
    "\n",
    "plot_learning_curves(record)  #横坐标是 steps"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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evXq4bbbbkNGRkax+2zcuBFDhgxRbSizur300ksltuW7775Dp06d1H26d++O6dOnIxhMmTIF/fv3VzO6Nm7cGFdccQV27NhR7D45OTm466670KBBA9StWxdXX301jh8/Xuw+Bw8exMUXX4yoqCj1OA8//DAKCgqK3WfBggXo06ePqshu164dPv300xqzP77zzjvo0aOHa2KdgQMHYsaMGa6/s41K9+KLL6rP3v333+/6HdsKmDRpkmoX95scHzS2UZEjR47ghhtuUG0hx2k5fq5evdqcx3HDBL7++msjLCzM+Pjjj40tW7YYt99+u1GvXj3j+PHjhhlMnz7deOKJJ4wff/xRRvAY06ZNK/b3F1980YiNjTV++uknY8OGDcZll11mtG7d2sjOznbd56KLLjJ69uxpLF++3Fi8eLHRrl07Y9y4ca6/p6amGk2aNDEmTJhgbN682fjqq6+MyMhI47333nPd548//jBsNpvx0ksvGVu3bjX+8Y9/GKGhocamTZuMQBs9erTxySefqG1fv369MXbsWKNFixZGRkaG6z533HGHkZiYaMydO9dYvXq1ce655xrnnXee6+8FBQVGt27djBEjRhjr1q1T7d6wYUPjsccec91n7969RlRUlPHAAw+oNnjjjTdUm8ycObNG7I+//PKL8dtvvxk7d+40duzYYTz++OPqPZR2E2yjklauXGm0atXK6NGjh3Hfffe5fs+2Moynn37a6Nq1q5GUlOS6nThxwvV3tpHD6dOnjZYtWxq33HKLsWLFCvWaZs2aZezevduUx3FTBBYDBgww7rrrLtfPdrvdaNq0qTFlyhTDbDwDi8LCQiM+Pt54+eWXXb87c+aMER4ernYqITuP/L9Vq1a57jNjxgzDYrEYR44cUT+//fbbRv369Y3c3FzXfR555BGjY8eOrp+vu+464+KLLy62Peecc47x17/+1Qg2ycnJ6jUvXLjQ1Sby4fnuu+9c99m2bZu6z7Jly9TPclCzWq3GsWPHXPd55513jJiYGFe7/P3vf1cHUnfXX3+9Cmxq6v4o7/uHH37INipFenq60b59e2POnDnG+eef7wos2FZFgYWc6ErDNjKKHUsHDx5slMVsx/Ea3xWSl5eHNWvWqLSR+3ok8vOyZctgdvv27cOxY8eKvX6Zy11Sgfr1y1dJm/Xr1891H7m/tNOKFStc9xk6dCjCwsJc9xk9erTqTkhJSXHdx/159H2CsZ1TU1PV17i4OPVV9hFZath9+yUV2KJFi2LtJGnBJk2aFHt9suDPli1bvGqDmrQ/2u12fP3118jMzFRdImyjkiSNL2l6z9fDtioi6Xrppm3Tpo1K00vXhmAbFfnll1/U8ffaa69V3T29e/fGBx98YNrjeI0PLE6ePKkOkO47ppCf5Y0yO/0ay3v98lV2ZnchISHqpOt+n9Iew/05yrpPsLWzrKArfeGDBg1Ct27d1O9kG+XDJh/M8tqpsm0gB8Ls7OwasT9u2rRJ9XdLf/Udd9yBadOmoUuXLmwjDxJ0rV27VtXveGJbOciJT+odZs6cqep35AQp/fuyAibbqMjevXtV+7Rv3x6zZs3C3/72N9x777347LPPTHkc9/vqpkT+uMrcvHkzlixZEuhNCUodO3bE+vXrVVbn+++/x80334yFCxcGerOCiixHfd9992HOnDmqwI1KN2bMGNf3UhQsgUbLli3x7bffqgJEKrrYkUzDCy+8oH6WjIUco9599131+TObGp+xaNiwIWw2W4lKY/k5Pj4eZqdfY3mvX74mJycX+7tUXUuFsft9SnsM9+co6z7B1M533303fv31V8yfPx/Nmzd3/V62UVKmZ86cKbedKtsGUqUtB9KasD/KVaRU1vft21ddjffs2ROvv/4628iNpNblMyMjEeSqUG4SfP3nP/9R38sVHtuqJMlOdOjQAbt37+b+5EZGekhW0F3nzp1d3UZmO47X+MBCDpJygJw7d26x6FB+ln5js2vdurXaIdxfv6QIpc9Nv375Kh9uOVhq8+bNU+0kVxj6PjKsVfpENblak6vb+vXru+7j/jz6PsHQzlLXKkGFpPXltUm7uJN9JDQ0tNj2S7+jfLDd20m6Cdw/vPL65ACmDwpna4OauD/K9uXm5rKN3AwfPly9Tsns6JtccUoNgf6ebVWSDH3cs2ePOpFyfyoi3bKew9937typsjumPI4bJiBDjaR69tNPP1WVs3/5y1/UUCP3SuOaTCrTZSiW3OQte/XVV9X3Bw4ccA1Tktf7888/Gxs3bjQuv/zyUocp9e7dWw11WrJkiap0dx+mJBXIMkzpxhtvVMOUpE1liJfnMKWQkBDjlVdeUdXdUhEeLMNN//a3v6mhWgsWLCg29C0rK6vY0DcZgjpv3jw19G3gwIHq5jn0bdSoUWrIqgxna9SoUalD3x5++GHVBm+99VapQ9+CdX989NFH1UiZffv2qX1Ffpaq8tmzZ6u/s43K5j4qRLCtDOPBBx9UnznZn+T4IMNGZbiojMoSbKOiIcty7Hz++eeNXbt2GV9++aV6TV988YXzHuY6jpsisBAytll2YBnLLEOPZJyvWcyfP18FFJ63m2++2TVU6cknn1Q7lHy4hg8fruYocHfq1Cm1A9atW1cN5Zo4caIKWNzJ2GkZEiWP0axZM7Wje/r222+NDh06qHaWIWAyJ0IwKK195CZzW2jyAb3zzjvVcCz5sF155ZUq+HC3f/9+Y8yYMWrstxwg5cCZn59f4v3o1auXaoM2bdoUe45g3x9vvfVWNZ5etksO4LKv6KBCsI28DyzYVo5hnwkJCWq75JghP7vPzcA2KvK///1PBVFyfO3UqZPx/vvvu/3VXMdxLptOREREPlPjayyIiIgoeDCwICIiIp9hYEFEREQ+w8CCiIiIfIaBBREREfkMAwsiIiLyGQYWRERE5DMMLIiIiMhnGFgQERGRzzCwIKIKueWWW3DFFVcEejOIKEgxsCAiIiKfYWBBRKX6/vvv0b17d0RGRqJBgwYYMWIEHn74YXz22Wf4+eefYbFY1G3BggXq/ocOHcJ1112HevXqIS4uDpdffjn2799fItMxefJkNGrUSC2NfccddyAvLy+Ar5KIfC3E549IRDVeUlISxo0bh5deeglXXnkl0tPTsXjxYtx00004ePAg0tLS8Mknn6j7ShCRn5+P0aNHY+DAgep+ISEheO6553DRRRdh48aNCAsLU/edO3cuIiIiVDAiQcfEiRNV0PL8888H+BUTka8wsCCiUgOLgoICXHXVVWjZsqX6nWQvhGQwcnNzER8f77r/F198gcLCQnz44YcqiyEk8JDshQQRo0aNUr+TAOPjjz9GVFQUunbtimeeeUZlQZ599llYrUygEpkBP8lEVELPnj0xfPhwFUxce+21+OCDD5CSklLm/Tds2IDdu3cjOjoadevWVTfJZOTk5GDPnj3FHleCCk0yHBkZGaobhYjMgRkLIirBZrNhzpw5WLp0KWbPno033ngDTzzxBFasWFHq/SU46Nu3L7788ssSf5N6CiKqPRhYEFGppEtj0KBB6vbUU0+pLpFp06ap7gy73V7svn369ME333yDxo0bq6LM8jIb2dnZqjtFLF++XGU3EhMTq/31EJF/sCuEiEqQzMQLL7yA1atXq2LNH3/8ESdOnEDnzp3RqlUrVZC5Y8cOnDx5UhVuTpgwAQ0bNlQjQaR4c9++faq24t5778Xhw4ddjysjQG677TZs3boV06dPx9NPP427776b9RVEJsKMBRGVIFmHRYsW4bXXXlMjQCRb8a9//QtjxoxBv379VNAgX6ULZP78+Rg2bJi6/yOPPKIKPmUUSbNmzVSdhnsGQ35u3749hg4dqgpAZeTJpEmTAvpaici3LIZhGD5+TCKiEmQeizNnzuCnn34K9KYQUTVi/pGIiIh8hoEFERER+Qy7QoiIiMhnmLEgIiIin2FgQURERD7DwIKIiIh8hoEFERER+QwDCyIiIvIZBhZERETkMwwsiIiIyGcYWBARERF85f8BfFgm6DkOlroAAAAASUVORK5CYII="
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 35
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 测试集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-16T14:30:02.716508Z",
     "start_time": "2025-01-16T14:30:02.633169Z"
    }
   },
   "source": [
    "model.eval()\n",
    "loss = evaluating(model, test_loader, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\")"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.3326\n"
     ]
    }
   ],
   "execution_count": 38
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
